/*
 *    Copyright (c) 2018-2025, proj All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the proj developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Author: proj
 */
package com.ykht.proj.coupon.service.impl;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ykht.proj.admin.api.entity.SysUser;
import com.ykht.proj.admin.api.feign.RemoteUserService;
import com.ykht.proj.admin.api.vo.UserVO;
import com.ykht.proj.common.core.constant.CommonConstants;
import com.ykht.proj.common.core.exception.BusinessException;
import com.ykht.proj.common.core.util.R;
import com.ykht.proj.common.security.util.SecurityUtils;
import com.ykht.proj.coupon.Enum.*;
import com.ykht.proj.coupon.entity.*;
import com.ykht.proj.coupon.mapper.*;
import com.ykht.proj.coupon.service.*;
import com.ykht.proj.coupon.vo.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.language.bm.RuleType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 优惠券领取记录表
 *
 * @author proj code generator
 * @date 2020-11-16 17:00:21
 */
@Service
@RequiredArgsConstructor(onConstructor_ = {@Lazy, @Autowired})
@Slf4j
@Transactional
public class CnCouponLogServiceImpl extends ServiceImpl<CnCouponLogMapper, CnCouponLog> implements CnCouponLogService {

	private final CnCouponLogMapper cnCouponLogMapper;

	private final CnCompanyService cnCompanyService;

	private final CnBrandService cnBrandService;

	private final CnShopService cnShopService;

	private final CnCouponMapper cnCouponMapper;

	private final CnCouShopMapper cnCouShopMapper;

	private final FxWaiterExtService fxWaiterExtService;

	private final FxConfRewardService fxConfRewardService;

	private final FxConfRewardBaseGlobelService fxConfRewardBaseGlobelService;

	private final FxRewardService fxRewardService;

	private final FxConfShopService fxConfShopService;

	private final FxConfRewardBaseService fxConfRewardBaseService;

	private final RemoteUserService remoteUserService;

	private final FxRewardPersonService fxRewardPersonService;

	private final FxMerchantAccountService fxMerchantAccountService;

	private final FxPersonAccountService fxPersonAccountService;
	private final FxConfBrandPersonMapper fxConfBrandPersonMapper;
	private final FxConfBrandPersonService fxConfBrandPersonService;


	@Override
	public R findPage(Page page, CnCouponLogVo cnCouponLogVo) {
		Integer userType = SecurityUtils.getUser().getUserType();
		Long sjId = SecurityUtils.getSjId();
		Long userId = SecurityUtils.getUserId();
		cnCouponLogVo.setLoginRoleType(userType);
		if (userType.equals(UserTypeEnum.company.getValue())) {
			cnCouponLogVo.setCompanyId(sjId);
		}
		if (userType.equals(UserTypeEnum.brand.getValue())) {
			cnCouponLogVo.setBrandIds(sjId.toString());
		}
		if (userType.equals(UserTypeEnum.shop.getValue())) {
			CnShop cnShop = cnShopService.getById(sjId);
			if (cnCouponLogVo.getFindType() == 0) {
				cnCouponLogVo.setShopId(cnShop.getId());
			} else {
				cnCouponLogVo.setVerificationShop(cnShop.getId());
				// 门店可以查看服务核销的
			/*	List<FxWaiterExt> waiterExtList = fxWaiterExtService.list(Wrappers.lambdaQuery(FxWaiterExt.class)
						.eq(FxWaiterExt::getShopId, cnShop.getId()).eq(FxWaiterExt::getDelFlag, 0));
				List<Long> longList = waiterExtList.stream().map(FxWaiterExt::getId).collect(Collectors.toList());
				cnCouponLogVo.setWaiterIdList(longList);*/
			}
		}
		if (userType.equals(UserTypeEnum.WAITER.getValue())) {
			FxWaiterExt waiterExt = fxWaiterExtService.getOne(Wrappers.lambdaQuery(FxWaiterExt.class)
					.eq(FxWaiterExt::getLoginId, userId).eq(FxWaiterExt::getDelFlag, 0)
					.eq(FxWaiterExt::getWorkState, WorkStateEnum.WORK_STATE_1.getValue()));
			if (cnCouponLogVo.getFindType() == 0) {
				cnCouponLogVo.setWaiterId(waiterExt.getId());
			} else {
				cnCouponLogVo.setVerificationShop(waiterExt.getId());
			}
		}
		List<CnCouponLogVo> list = cnCouponLogMapper.findPage(page, cnCouponLogVo);
		if (list != null && list.size() > 0) {
			for (CnCouponLogVo cnCouponLog : list) {
				isOverdue(cnCouponLog);
			}
		}
		Set<Long> set = list.stream().map(CnCouponLogVo::getVerificationLoginId).filter(o -> o != null).collect(Collectors.toSet());
		Map<Long, SysUser> userMap = remoteUserService.userByIds(ListUtil.toList(set)).stream().collect(Collectors.toMap(o->Long.valueOf(o.getUserId()), Function.identity()));
		list.stream().forEach(o->{
			SysUser user = userMap.get(o.getVerificationLoginId());
			if (user!=null){
				o.setVerificationLoginName(o.getVerificationType()==2?user.getUsername():user.getNickName());
				o.setVerificationLoginPhone(user.getPhone());
			}
		});

		return R.ok(page.setRecords(list));
	}


	@Override
	public R getCouponLogPagelRespById(CouponLogPagelReq req) {
		CouponLogPagelResp resp = cnCouponLogMapper.getCouponLogPagelRespById(req);
		if (resp == null) return R.failed("违法的参数");
		resp = this.getCouponLogPagelResp(resp, req);
		return R.ok(resp);
	}

	@Override
	public Object getAllCoupon(FxCmsInfoVO fxCmsInfoVO) {
		String[] arr = fxCmsInfoVO.getCouponId().split(",");
		for (int i = 0; i < arr.length; i++) {
			CnCouponLog cnCouponLog = new CnCouponLog();
			cnCouponLog.setCreateUser(SecurityUtils.getUserId());
			cnCouponLog.setCreateTime(LocalDateTime.now());
			cnCouponLog.setCouponId(Long.parseLong(arr[i]));
			cnCouponLogMapper.insert(cnCouponLog);
		}
		return null;
	}

	@Override
	public CouponLogCount myCouponCount(Long personId) {
		List<CouponLogTypeCount> list  = cnCouponLogMapper.myCouponCount(personId);
		CouponLogCount couponLogCount = new CouponLogCount();
		list.stream().forEach(o->{
			if (0==o.getStatus()) couponLogCount.setWsyNum(o.getNum());
			if (1==o.getStatus()) couponLogCount.setYsyNum(o.getNum());
			if (2==o.getStatus()) couponLogCount.setYgqNum(o.getNum());
		});
		return couponLogCount;
	}

	@Override
	public IPage<CouponLogPagelResp> opPage(Page page, CouponLogPagelReq req) {
		IPage<CouponLogPagelResp> resp = cnCouponLogMapper.opPage(page, req);
		resp.getRecords().stream().forEach(o -> {
			o = this.getCouponLogPagelResp(o, req);
		});
		return resp;
	}

	public CouponLogPagelResp getCouponLogPagelResp(CouponLogPagelResp o, CouponLogPagelReq req) {
		//附近门店
		List<CnShopDisVo> list = null;
		if (0 == o.getType()) {//全门店
			CnShopDisVo cnShopDisVo = new CnShopDisVo();
			cnShopDisVo.setBrandId(o.getBrandId());
			cnShopDisVo.setLatitude(req.getLatitude());
			cnShopDisVo.setLongitude(req.getLongitude());
			list = cnShopService.shopAndDistant(cnShopDisVo);

		} else {//多门店和单门店
			list = cnShopService.shopAndDistant4NotTyCoupon(req.getLatitude(), req.getLongitude(), o.getCouponId());
			list = list.stream().filter(oo -> oo != null && oo.getId() != null).collect(Collectors.toList());//过滤门店id不存在的数据
		}

		if (list.size() == 0) return o;
		o.setShopId(list.get(0).getId());
		o.setShopName(list.get(0).getName());
		o.setLatitude(list.get(0).getLatitude());
		o.setLongitude(list.get(0).getLongitude());
		o.setDistance(list.get(0).getDistance());
		o.setAddress(list.get(0).getAddress());
		o.setPhone(list.get(0).getPhone());
		o.setNum(list.size());
		return o;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public R writeOff(CnCouponLog cnCouponLog) {
			Integer userType = SecurityUtils.getUser().getUserType();
			Long verificationShop = null; //核销人ID
			Long loginShopId = null; // 登录人门店ID
			Long brandId = null; //品牌ID
			//  创建核销奖励记录
			FxReward fxReward = new FxReward();
			if (userType.equals(UserTypeEnum.WAITER.getValue())) {
				FxWaiterExt waiterExt = fxWaiterExtService.getOne(Wrappers.lambdaQuery(FxWaiterExt.class)
						.eq(FxWaiterExt::getLoginId, SecurityUtils.getUserId())
						.eq(FxWaiterExt::getWorkState, WorkStateEnum.WORK_STATE_1.getValue())
						.eq(FxWaiterExt::getDelFlag, 0));
				fxReward.setShopId(waiterExt.getShopId());
				loginShopId = waiterExt.getShopId();
				log.info("核销服务员Id{}", waiterExt.getId());
				verificationShop = waiterExt.getId();
				cnCouponLog.setVerificationType(1);
				brandId = waiterExt.getBrandId();
			} else {
				CnShop cnShop = cnShopService.getById(SecurityUtils.getSjId());
				fxReward.setShopId(cnShop.getId());
				loginShopId = cnShop.getId();
				log.info("核销门店Id{}", cnShop.getId());
				verificationShop = cnShop.getId();
				cnCouponLog.setVerificationType(2);
				brandId = cnShop.getBrandId();
			}
			CnCouponLog one = this.getOne(Wrappers.lambdaQuery(CnCouponLog.class).eq(CnCouponLog::getVerificationCode,
					cnCouponLog.getVerificationCode()));
			CnCoupon cnCoupon = cnCouponMapper.selectById(one.getCouponId());
			Boolean aBoolean = false;
			if (null != one.getWaiterId()) {
				FxWaiterExt waiterExt = fxWaiterExtService.getOne(Wrappers.lambdaQuery(FxWaiterExt.class)
						.eq(FxWaiterExt::getId, one.getWaiterId()).eq(FxWaiterExt::getDelFlag, 0));
				List<FxWaiterExt> waiterExtList = fxWaiterExtService.list(Wrappers.lambdaQuery(FxWaiterExt.class)
						.eq(FxWaiterExt::getLoginId, waiterExt.getLoginId())
						.in(FxWaiterExt::getWorkState, WorkStateEnum.WORK_STATE_1.getValue(),
								WorkStateEnum.WORK_STATE_2.getValue())
						.eq(FxWaiterExt::getBrandId, waiterExt.getBrandId()).eq(FxWaiterExt::getDelFlag, 0));
				if (null != waiterExtList && waiterExtList.size() > 0) {
					for (FxWaiterExt fxWaiterExt : waiterExtList) {
						if (loginShopId.equals(fxWaiterExt.getShopId())) {
							aBoolean = true;
						}
					}
				}
			}
			if (null != one.getWaiterId() && aBoolean) {
				BigDecimal rewardMoney = BigDecimal.valueOf(0);
				//如果平台分销总开关关了、不给钱
				FxConfRewardBaseGlobel fxConfRewardBaseGlobel = fxConfRewardBaseGlobelService.getOne(Wrappers.lambdaQuery(FxConfRewardBaseGlobel.class)
						.eq(FxConfRewardBaseGlobel::getDelFlag, 0)
						.eq(FxConfRewardBaseGlobel::getSwitchs, 0)
				);
				if (fxConfRewardBaseGlobel != null) {
					FxConfRewardBase fxConfRewardBase = fxConfRewardBaseService.getOne(Wrappers.lambdaQuery(FxConfRewardBase.class)
							.eq(FxConfRewardBase::getBrandId, brandId)
							.eq(FxConfRewardBase::getDelFlag, 0)
							.eq(FxConfRewardBase::getSwitchs, 0)
					);
					//如果品牌分销开关 关了、也不给钱
					if (fxConfRewardBase != null) {
						// 获取品牌核销佣金配置
						List<FxConfReward> rewardList = fxConfRewardService.list(Wrappers.lambdaQuery(FxConfReward.class)
								.eq(FxConfReward::getBrandId, one.getBrandId())
								.eq(FxConfReward::getRuleType, DistributionTypeEnum.DISTRIBUTION_TYPE_2.getValue())
								.eq(FxConfReward::getCouponType, cnCoupon.getCouponType())
								.eq(FxConfReward::getStatus, 0).eq(FxConfReward::getDelFlag, 0));
						FxConfShop fxConfShop = null;
						FxConfReward fxConfReward = null;
						//  循环判断品牌核销佣金配置 查看是否有门店的佣金配置
						if (null != rewardList && rewardList.size() > 0) {
							for (FxConfReward reward : rewardList) {
								fxConfShop = fxConfShopService.getOne(Wrappers.lambdaQuery(FxConfShop.class)
										.eq(FxConfShop::getBrandId, one.getBrandId())
										.eq(FxConfShop::getConfRewardId, reward.getId())
										.eq(FxConfShop::getShopId, cnCouponLog.getShopId())
										.eq(FxConfShop::getDelFlag, 0));
								if (fxConfShop != null && null != fxConfShop.getId()) {
									fxConfReward = reward;
									break;
								}
							}
						}
						if (fxConfShop != null) {
							rewardMoney = fxConfReward.getRewardType().equals(0) ? fxConfReward.getBaseMoney()
									: (fxConfReward.getPercent().multiply(cnCouponLog.getPayMoney()).multiply(BigDecimal.valueOf(0.01)));
							// 品牌的金额不能低于平台的金额
							if (rewardMoney.compareTo(fxConfRewardBaseGlobel.getUseCouponMoney()) == -1) {
								rewardMoney = fxConfRewardBaseGlobel.getUseCouponMoney();
							}
						} else {
							rewardMoney = fxConfRewardBaseGlobel.getUseCouponMoney();
						}
					}
				}
				cnCouponLog.setRewardMoney(rewardMoney.doubleValue());
				fxReward.setCompanyId(one.getCompanyId());
				fxReward.setBrandId(one.getBrandId());
				fxReward.setWaiterId(one.getWaiterId());
				fxReward.setFyId(one.getFyId());
				fxReward.setType(DistributionTypeEnum.DISTRIBUTION_TYPE_2.getValue());
				fxReward.setUseMoney(cnCouponLog.getCnMoney());
				fxReward.setCreateUser(SecurityUtils.getUserId());
				fxReward.setCreateTime(LocalDateTime.now());
				fxReward.setDelFlag(0);
				fxReward.setMoney(rewardMoney);
				fxReward.setTatId(one.getId());
				fxRewardService.save(fxReward);
		}
		cnCouponLog.setVerificationShop(verificationShop);
		cnCouponLog.setVerificationType(userType == UserTypeEnum.WAITER.getValue() ? 1 : 2);
		UserVO byIdUser = remoteUserService.getByIdUser(SecurityUtils.getUserId());
		cnCouponLog.setVerificationPerson(userType == UserTypeEnum.WAITER.getValue() ? byIdUser.getNickName() : byIdUser.getUsername());
		cnCouponLog.setVerificationShopId(loginShopId);
		cnCouponLog.setStatus(1);
		cnCouponLog.setVerificationLoginId(SecurityUtils.getUserId());

		cnCouponLog.setVerificationTime(LocalDateTime.now());
		UpdateWrapper<CnCouponLog> updateWrapper = new UpdateWrapper<>();
		updateWrapper.lambda().eq(CnCouponLog::getVerificationCode, cnCouponLog.getVerificationCode());
		cnCouponLogMapper.update(cnCouponLog, updateWrapper);

		CnCouponLog couponLog = this.getOne(Wrappers.lambdaQuery(CnCouponLog.class).eq(CnCouponLog::getVerificationCode, cnCouponLog.getVerificationCode()));
		//添加c端分销后的优惠券核销
		this.shareFx(couponLog);

		return R.ok(true);

	}
	void shareFx(CnCouponLog couponLog){
		if (couponLog != null && couponLog.getShareUserId() != null){
			FxConfBrandPerson fxConfBrandPerson = fxConfBrandPersonService.findEnableConf(couponLog.getBrandId());
			if (fxConfBrandPerson!=null){
				int reduceFlag = 0;
				try {
					fxConfBrandPersonMapper.updateStatistics(couponLog.getBrandId(),-1,1,0);
				} catch (Exception e) {
					//SurplusPush为非负数，减库存小于0就报错
					log.info("****************减库存失败,已捕获走库存为0的逻辑**************");
					reduceFlag = 1;
				}
				if (reduceFlag == 0){
					fxRewardPersonService.update(Wrappers.lambdaUpdate(FxRewardPerson.class)
							.set(FxRewardPerson::getMoney,fxConfBrandPerson.getReturnMoney())
							.set(FxRewardPerson::getStatus,RewardPersonEnum.not_push.getValue())
							.eq(FxRewardPerson::getTatId,couponLog.getId()));
					couponLog.setReturnMoney(fxConfBrandPerson.getReturnMoney());
					couponLog.setFxStatus(0);//待审核
					couponLog.updateById();
				}
			}
		}
	}


	/**
	 * 核销优惠卷 验证
	 *
	 * @param verificationCode
	 * @return
	 */
	@Override
	public R findByCode(String verificationCode) {
		Integer userType = SecurityUtils.getUser().getUserType();
		Long shopId = SecurityUtils.getSjId();
		if (userType.equals(UserTypeEnum.WAITER.getValue())) {
			FxWaiterExt waiterExt = fxWaiterExtService.getOne(Wrappers.lambdaQuery(FxWaiterExt.class)
					.eq(FxWaiterExt::getLoginId, SecurityUtils.getUserId())
					.eq(FxWaiterExt::getWorkState, WorkStateEnum.WORK_STATE_1.getValue())
					.eq(FxWaiterExt::getDelFlag, 0));
			shopId = waiterExt.getShopId();
		}
		CnShop one = cnShopService.getById(shopId);
		log.info("获取登录人所在门店信息：{}", one);
		CnCouponLog cnCouponLog = cnCouponLogMapper.selectOne(Wrappers.lambdaQuery(CnCouponLog.class)
				.eq(CnCouponLog::getVerificationCode, verificationCode).eq(CnCouponLog::getBrandId, one.getBrandId()));
		log.info("获取优惠券是否在登录人的品牌下：{}", cnCouponLog);
		if (cnCouponLog != null) {
			CnCoupon coupon = cnCouponMapper.selectById(cnCouponLog.getCouponId());
			CnCouponVo cnCouponVo = BeanUtil.toBean(coupon, CnCouponVo.class);
			if (coupon.getType().equals(CouponEnum.single.getValue())) {
				CnCouShop cnCouShop = cnCouShopMapper.selectOne(Wrappers.lambdaQuery(CnCouShop.class)
						.eq(CnCouShop::getCouId, coupon.getId()));
				if (!cnCouShop.getShopId().equals(one.getId())) {
					return R.failed("不是本门店的优惠券");
				}
				cnCouponVo.setShopName(one.getName());
			} else if (coupon.getType().equals(CouponEnum.many.getValue())) {
				CnCouShop cnCouShop1 = cnCouShopMapper.selectOne(Wrappers.lambdaQuery(CnCouShop.class)
						.eq(CnCouShop::getCouId, coupon.getId())
						.eq(CnCouShop::getShopId, one.getId()));
				if (null == cnCouShop1) {
					return R.failed("不是本门店的优惠券");
				}
				Integer count = cnCouShopMapper.selectCount(Wrappers.lambdaQuery(CnCouShop.class)
						.eq(CnCouShop::getCouId, coupon.getId()));
				if (count != null && count == 1) {
					CnCouShop cnCouShop = cnCouShopMapper.selectOne(Wrappers.lambdaQuery(CnCouShop.class)
							.eq(CnCouShop::getCouId, coupon.getId()));
					cnCouponVo.setShopName(cnShopService.getById(cnCouShop.getShopId()).getName());
				} else {
					cnCouponVo.setShopName("共" + count + "家可用");
				}
			} else {
				int count = cnShopService.count(Wrappers.lambdaQuery(CnShop.class)
						.eq(CnShop::getBrandId, one.getBrandId()));
				if (count == 1) {
					cnCouponVo.setShopName(one.getName());
				} else {
					cnCouponVo.setShopName("共" + count + "家可用");
				}
			}
			CnCouponLogVo cnCouponLogVo = BeanUtil.toBean(cnCouponLog, CnCouponLogVo.class);
			cnCouponLogVo.setDateType(cnCouponVo.getDateType());
			cnCouponLogVo.setEffectiveeDay(cnCouponVo.getEffectiveeDay());
			cnCouponLogVo.setEffectiveeStaTime(cnCouponVo.getEffectiveeStaTime());
			cnCouponLogVo.setEffectiveeEndTime(cnCouponVo.getEffectiveeEndTime());
			isOverdue(cnCouponLogVo);
			cnCouponVo.setCoustatus(cnCouponLogVo.getStatus());
			cnCouponVo.setValidity(cnCouponLogVo.getValidity());
			return R.ok(cnCouponVo);
		} else {
			return R.failed("请输入该品牌下正确的优惠码");
		}
	}

	private void isOverdue(CnCouponLogVo cnCouponLog) {
		if (cnCouponLog.getDateType().equals(CouponDateEnum.days.getValue())) {
			cnCouponLog.setValidity("领取后" + cnCouponLog.getEffectiveeDay() + "天内有效");
			if (cnCouponLog.getStatus().equals(0)) {//待使用//并且是领取后几天内有效的
				long l = cnCouponLog.getReceiveTime().plusDays(cnCouponLog.getEffectiveeDay().longValue())
						.toEpochSecond(ZoneOffset.of("+8"));
				long l1 = LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8"));
				if (l1 > l) {
					cnCouponLog.setStatus(2);//过期状态
				}
			}
		} else {
			DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
			cnCouponLog.setValidity(formatter.format(cnCouponLog.getEffectiveeStaTime())+" 00:00:00" + "至" + formatter.format(cnCouponLog.getEffectiveeEndTime()) + " 23:59:59");
			if (cnCouponLog.getStatus().equals(0)) {//待使用//时间段内有效
				long l = cnCouponLog.getEffectiveeEndTime().toInstant(ZoneOffset.of("+8")).toEpochMilli();
				long l2 = cnCouponLog.getEffectiveeStaTime().toInstant(ZoneOffset.of("+8")).toEpochMilli();
				long l1 = LocalDate.now().atStartOfDay().toInstant(ZoneOffset.of("+8")).toEpochMilli();
				if (l2 > l1) {
					cnCouponLog.setStatus(3);//未到使用时间
				} else if (l1 > l) {
					cnCouponLog.setStatus(2);//过期状态
				}
			}
		}
	}

	@Override
	public String QRcode(String verificationCode) {
		String tokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=wxd45827cc3ced6125&secret=45a2ef08e1347426abbd632b66538f02";
		String data = HttpUtil.get(tokenUrl);
		String access_token = JSONUtil.parseObj(data).getStr("access_token");
		String url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + access_token;
		HttpResponse response = HttpUtil.createPost(url)
				.body(JSONUtil.createObj().putOpt("scene", verificationCode).putOpt("path", "pages/tabs/mine").toString())
				.execute();
		byte[] result = response.bodyBytes();
		String base64 = Base64.encodeBase64String(result);
//		log.info("小程序二维码：{}",base64);
		//data:image/jpeg;base64,加上base64 可以再浏览器上直接打开
		return base64;
	}

	/*	public static void main(String[] args) {
	//		String b____tokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=wxd45827cc3ced6125&secret=45a2ef08e1347426abbd632b66538f02";
			String c____tokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=wxee07aa457f3084a5&secret=bd904fb6b03d5d3a75f26fa9b707452e";
			String data = HttpUtil.get(c____tokenUrl);
			String access_token = JSONUtil.parseObj(data).getStr("access_token");
			String url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token="+access_token;
			HttpResponse response = HttpUtil.createPost(url)
					.body(JSONUtil.createObj().putOpt("scene","0").putOpt("page","pages/actives/active_list").toString())
					.execute();
			byte[] result = response.bodyBytes();
			String base64 = Base64.encodeBase64String(result);
			log.info("小程序二维码：{}",base64);
			log.info("小程序二维码：data:image/jpeg;base64,{}",base64);
			//data:image/jpeg;base64,加上base64 可以再浏览器上直接打开
		}*/
	@Override
	public R getCouponById(Long id) {
		CnCoupon coupon = cnCouponMapper.selectById(id);
		CnBrand cnBrand = cnBrandService.getById(coupon.getBrandId());
		CnCouponVo cnCouponVo = BeanUtil.toBean(coupon, CnCouponVo.class);
		cnCouponVo.setBrandName(cnBrand.getBrandName());
		if (coupon.getType().equals(CouponEnum.single.getValue())) {
			getShop(coupon.getId(), cnCouponVo);
		} else if (coupon.getType().equals(CouponEnum.many.getValue())) {
			Integer count = cnCouShopMapper.selectCount(Wrappers.lambdaQuery(CnCouShop.class)
					.eq(CnCouShop::getCouId, coupon.getId()));
			if (count != null && count == 1) {
				getShop(coupon.getId(), cnCouponVo);
			} else {
				cnCouponVo.setShopName("共" + count + "家可用");
			}
		} else {
			int count = cnShopService.count(Wrappers.lambdaQuery(CnShop.class)
					.eq(CnShop::getBrandId, coupon.getBrandId()));
			if (count == 1) {
				cnCouponVo.setShopName(cnShopService.getOne(Wrappers.lambdaQuery(CnShop.class)
						.eq(CnShop::getBrandId, coupon.getBrandId())).getName());
			} else {
				cnCouponVo.setShopName("共" + count + "家可用");
			}
		}
		cnCouponVo.setLogoUrl(cnBrand.getLogoUrl());
		return R.ok(cnCouponVo);
	}

	public void getShop(Long id, CnCouponVo cnCouponVo) {
		CnCouShop cnCouShop = cnCouShopMapper.selectOne(Wrappers.lambdaQuery(CnCouShop.class)
				.eq(CnCouShop::getCouId, id));
		cnCouponVo.setShopName(cnShopService.getById(cnCouShop.getShopId()).getName());
	}

	@Override
	public R queryById(Long id) {
		CnCouponLog cnCouponLog = this.getById(id);
		CnCoupon coupon = cnCouponMapper.selectById(cnCouponLog.getCouponId());
		CnCouponVo cnCouponVo = BeanUtil.toBean(coupon, CnCouponVo.class);
		if (coupon.getType().equals(CouponEnum.single.getValue())) {
			CnCouShop cnCouShop = cnCouShopMapper.selectOne(Wrappers.lambdaQuery(CnCouShop.class)
					.eq(CnCouShop::getCouId, coupon.getId()));
			cnCouponVo.setShopName(cnShopService.getById(cnCouShop.getShopId()).getName());
		} else if (coupon.getType().equals(CouponEnum.many.getValue())) {
			Integer count = cnCouShopMapper.selectCount(Wrappers.lambdaQuery(CnCouShop.class)
					.eq(CnCouShop::getCouId, coupon.getId()));
			if (count != null && count == 1) {
				CnCouShop cnCouShop = cnCouShopMapper.selectOne(Wrappers.lambdaQuery(CnCouShop.class)
						.eq(CnCouShop::getCouId, coupon.getId()));
				cnCouponVo.setShopName(cnShopService.getById(cnCouShop.getShopId()).getName());
			} else {
				cnCouponVo.setShopName("共" + count + "家可用");
			}
		} else {
			int count = cnShopService.count(Wrappers.lambdaQuery(CnShop.class)
					.eq(CnShop::getBrandId, coupon.getBrandId()));
			if (count == 1) {
				cnCouponVo.setShopName(cnShopService.getOne(Wrappers.lambdaQuery(CnShop.class)
						.eq(CnShop::getBrandId, coupon.getBrandId())).getName());
			} else {
				cnCouponVo.setShopName("共" + count + "家可用");
			}
		}
		CnCouponLogVo cnCouponLogVo = BeanUtil.toBean(cnCouponLog, CnCouponLogVo.class);
		cnCouponLogVo.setDateType(cnCouponVo.getDateType());
		cnCouponLogVo.setEffectiveeDay(cnCouponVo.getEffectiveeDay());
		cnCouponLogVo.setEffectiveeStaTime(cnCouponVo.getEffectiveeStaTime());
		cnCouponLogVo.setEffectiveeEndTime(cnCouponVo.getEffectiveeEndTime());
		isOverdue(cnCouponLogVo);
		cnCouponVo.setCoustatus(cnCouponLogVo.getStatus());
		cnCouponVo.setValidity(cnCouponLogVo.getValidity());
		cnCouponVo.setTabNum(cnCouponLogVo.getTabNum());
		cnCouponVo.setPayMoney(cnCouponLogVo.getPayMoney());
		cnCouponVo.setCnMoney(cnCouponLogVo.getCnMoney());
		cnCouponVo.setVerificationPerson(cnCouponLogVo.getVerificationPerson());
		cnCouponVo.setVerificationCode(cnCouponLogVo.getVerificationCode());
		cnCouponVo.setVerificationTime(cnCouponLogVo.getVerificationTime());
		return R.ok(cnCouponVo);
	}

	/**
	 * 优惠券领取记录表 审核
	 *
	 * @param cnCouponLog
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void updateCheckStatus(CnCouponLog cnCouponLog) {
		this.updateById(cnCouponLog);
		CnCouponLog couponLog = this.getById(cnCouponLog.getId());

		FxConfBrandPerson brandPerson = this.checkAndFindOne(couponLog);
		// 审核通过 先给 c端奖励记录表给有效  在给c端账户表转账
		if (couponLog.getFeedbackStatus() == 1 && couponLog.getCheckStatus() != null && couponLog.getCheckStatus() == 1){//品牌拒绝，然后平台拒绝了品牌，所以发钱
			UpdateWrapper<FxRewardPerson> updateWrapper = new UpdateWrapper();
			updateWrapper.lambda().set(FxRewardPerson::getStatus, 2)
					.eq(FxRewardPerson::getShopType, 1)
					.set(FxRewardPerson::getPassTime, LocalDateTime.now())
					.eq(FxRewardPerson::getTatId, couponLog.getId());
			fxRewardPersonService.update(updateWrapper);
			FxPersonAccount fxPersonAccount = fxPersonAccountService.getOne(Wrappers.lambdaQuery(FxPersonAccount.class)
					.eq(FxPersonAccount::getPersonId, couponLog.getShareUserId()));
			// 该用户没有账号就创建
			if (null == fxPersonAccount){
				fxPersonAccount = new FxPersonAccount();
				fxPersonAccount.setType(0);
				fxPersonAccount.setPersonId(couponLog.getShareUserId());
				fxPersonAccount.setAccount(String.format(CommonConstants.ACCONCE_FORMAT, couponLog.getShareUserId()));
				fxPersonAccount.setBalance(BigDecimal.ZERO);
				fxPersonAccount.setBalanceTotal(BigDecimal.ZERO);
				fxPersonAccount.setBalanceFrozen(BigDecimal.ZERO);
				fxPersonAccount.setWithdrawal(BigDecimal.ZERO);
				fxPersonAccount.setCreateUser(SecurityUtils.getUserId());
				fxPersonAccount.setCreateTime(LocalDateTime.now());
				fxPersonAccountService.save(fxPersonAccount);
			}
			if (brandPerson==null) throw new BusinessException("该品牌当前时间未开启分销");
			//加c端用户
			fxPersonAccountService.updateFxPersonAccount(couponLog.getShareUserId(), 0, couponLog.getReturnMoney(), couponLog.getReturnMoney(),couponLog.getReturnMoney().negate(),null, SecurityUtils.getUserId());
			//减公司账户
			fxMerchantAccountService.updateMerchantAccount(MerchantTypeEnum.brand.getValue(),couponLog.getBrandId(),null,brandPerson.getReturnMoney().negate(),brandPerson.getReturnMoney().negate(),null,
						brandPerson.getReturnMoney(),null,SecurityUtils.getUserId());
			//增加核销通过数量,冻结数量减一
			fxConfBrandPersonMapper.updateStatistics(couponLog.getBrandId(),0,-1,1);

		} else {
			couponLog.setFxStatus(FxStatusEnum.INVALID.getValue());
			cnCouponLog.updateById();
			//剩余数量=投放数量-(已发放的数量+待确认发放数量）
			//z确定不发放佣金之后加回剩余数量和减去冻结数量
			fxConfBrandPersonMapper.updateStatistics(couponLog.getBrandId(),1,-1,0);
			//佣金返还给商家
			FxConfBrandPerson confBrandPerson = fxConfBrandPersonService.getById(cnCouponLog.getConfBrandPersonId());
			//活动是否进行
			if (confBrandPerson == null) throw new BusinessException("品牌配置异常");
			switch (BrandFxSwitchTypeEnum.getThisByVal(confBrandPerson.getSwitchs())){
				case RUNNING:
					//是，增推广剩余数量
					fxConfBrandPersonMapper.updateStatistics(couponLog.getBrandId(),1,-1,0);
					break;
				case FINISHED:
					//否，解冻变为商家可用余额
					fxConfBrandPersonMapper.updateStatistics(couponLog.getBrandId(),0,-1,0);
					fxMerchantAccountService.updateMerchantAccount(MerchantTypeEnum.brand.getValue(), confBrandPerson.getBrandId(), confBrandPerson.getReturnMoney(),
							confBrandPerson.getReturnMoney(), null, null, null, null, SecurityUtils.getUserId());
					break;
				default:
					throw new BusinessException("品牌配置异常");
			}
		}
	}

	FxConfBrandPerson checkAndFindOne(CnCouponLog couponLog){
		FxConfBrandPerson brandPerson = fxConfBrandPersonService.findEnableConf(couponLog.getBrandId());
		if (brandPerson==null){
			throw new BusinessException("该品牌当前时间未开启分销");
		}
//		if (brandPerson.getSurplusPushNum()==0){
//			throw new BusinessException("品牌分销次数为0");
//		}
		if (couponLog.getReturnMoney().compareTo(BigDecimal.ZERO)==0){
			throw new BusinessException("该数据不可以被修改");
		}
		return brandPerson;
	}
	/**
	 * 优惠券领取记录表 反馈状态
	 *
	 * @param cnCouponLog
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void updateFeedbackStatus(CnCouponLog cnCouponLog) {
		this.updateById(cnCouponLog);
		CnCouponLog byId = this.getById(cnCouponLog.getId());

		FxConfBrandPerson brandPerson = this.checkAndFindOne(byId);
		// 反馈有效给 先给 c端奖励记录表给有效  在给c端账户表转账
		if (byId.getFeedbackStatus() != null && byId.getFeedbackStatus().equals(0)) {
			UpdateWrapper<FxRewardPerson> updateWrapper = new UpdateWrapper();
			updateWrapper.lambda().set(FxRewardPerson::getStatus, 2)
					.set(FxRewardPerson::getPassTime, LocalDateTime.now())
					.eq(FxRewardPerson::getShopType, 1)
					.eq(FxRewardPerson::getTatId, byId.getId());
			fxRewardPersonService.update(updateWrapper);
			FxPersonAccount fxPersonAccount = fxPersonAccountService.getOne(Wrappers.lambdaQuery(FxPersonAccount.class)
					.eq(FxPersonAccount::getPersonId, byId.getShareUserId()));
			// 该用户没有账号就创建
			if (null == fxPersonAccount){
				fxPersonAccount = new FxPersonAccount();
				fxPersonAccount.setType(0);
				fxPersonAccount.setPersonId(byId.getShareUserId());
				fxPersonAccount.setAccount(String.format(CommonConstants.ACCONCE_FORMAT, byId.getShareUserId()));
				fxPersonAccount.setBalance(BigDecimal.ZERO);
				fxPersonAccount.setBalanceTotal(BigDecimal.ZERO);
				fxPersonAccount.setBalanceFrozen(BigDecimal.ZERO);
				fxPersonAccount.setWithdrawal(BigDecimal.ZERO);
				fxPersonAccount.setCreateUser(SecurityUtils.getUserId());
				fxPersonAccount.setCreateTime(LocalDateTime.now());
				fxPersonAccountService.save(fxPersonAccount);
			}
			byId.setFxStatus(FxStatusEnum.UN_CHECK.getValue());
			byId.updateById();
			if (brandPerson==null) throw new BusinessException("该品牌当前时间未开启分销");
			//加c端用户
			fxPersonAccountService.updateFxPersonAccount(byId.getShareUserId(), 0, byId.getReturnMoney(), byId.getReturnMoney(), byId.getReturnMoney(),null, SecurityUtils.getUserId());
			//减公司账户
			fxMerchantAccountService.updateMerchantAccount(MerchantTypeEnum.brand.getValue(),byId.getBrandId(),null,brandPerson.getReturnMoney().negate(),brandPerson.getReturnMoney().negate(),null,
					brandPerson.getReturnMoney(),null,SecurityUtils.getUserId());
			//增加核销通过数量,冻结数量减一
			fxConfBrandPersonMapper.updateStatistics(byId.getBrandId(),0,-1,1);
		}
	}

	/**
	 * 通过id查询优惠券领取记录表
	 *
	 * @param id
	 * @return
	 */
	@Override
	public CnCouponLogVo getByIdCnCouponLog(Long id) {
		CnCouponLogVo couponLog = cnCouponLogMapper.getByIdCnCouponLog(id);
		if (null != couponLog.getVerificationType()){
			UserVO userVO = remoteUserService.getByIdUser(couponLog.getVerificationType().equals(1)
					? couponLog.getWaiterLoginId() : couponLog.getShopLoginId());
			couponLog.setVerificationPersonName(couponLog.getVerificationType().equals(1)
					? userVO.getNickName() : userVO.getUsername());
			couponLog.setVerificationPersonPhone(userVO.getPhone());
		}
		if (null != couponLog.getCheckUser()){
			UserVO checkUser = remoteUserService.getByIdUser(couponLog.getCheckUser());
			couponLog.setCheckUserName(checkUser.getUsername());
		}
		return couponLog;
	}

	@Override
	public Page<PaymentVo> getPaymentPage(PaymentVo paymentVo) {
		Page<PaymentVo> page=cnCouponLogMapper.getPaymentPage(paymentVo);
		return page;
	}

	@Override
	public R getePosit(Long sjId) {
		return R.ok(cnCouponLogMapper.getePosit(sjId)) ;
	}

	@Override
	public R getPayment(Long sjId) {
		return R.ok(cnCouponLogMapper.getPayment(sjId)) ;
	}
}
